package com.pig4cloud.pigx.robot.ws.collect.okx;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.pig4cloud.pigx.robot.ws.collect.FetchManager;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.WebSocket;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Slf4j
public class WsManager {

    private static WsManager mInstance = null;
    public WebSocket webSocket;
    private OkHttpClient client;
    public Boolean isConnect = false;
    private Request request;
    private int subscribe_id = 1;
    public FetchManager fetchManager;
    /**
     * Streaming API base URL.
     */
    public static final String WS_API_BASE_URL = "wss://ws.okx.com:8443/ws/v5/public";

    private WsManager() {
    }

    public static WsManager getInstance() {
        if (null == mInstance) {
            synchronized (WsManager.class) {
                if (mInstance == null) {
                    mInstance = new WsManager();
                }
            }
        }
        return mInstance;
    }

    public void init(FetchManager fManager) {
        fetchManager = fManager;
        client = new OkHttpClient.Builder()
                .pingInterval(10, TimeUnit.SECONDS)
                .build();
        request = new Request.Builder()
                .url(WS_API_BASE_URL)
                .build();

        connect();
        heartbeat();
        reConnection();
    }

    /**
     * 连接
     */
    public void connect() {
        if (isConnect()) {
            log.info("WebSocket 已经连接！");
            return;
        }
        webSocket = client.newWebSocket(request, new WsListener());
    }

    /**
     * 心跳检测
     */
    private void heartbeat() {
        ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
        service.scheduleAtFixedRate(() -> {
            try {
                if (isConnect) {
                    sendMessage("ping");
                }
            } catch (Exception ex) {

            }
        }, 15, 25, TimeUnit.SECONDS);

    }

    /**
     * 断线 重连
     */
    public void reConnection() {
        ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
        service.scheduleAtFixedRate(() -> {
            try {
                if (!isConnect) {
                    connect();
                }
            } catch (Exception ex) {
                log.error("reconnection binance error:{0}", ex.getMessage());
            }
        }, 30, 30, TimeUnit.SECONDS);
    }

    /**
     * 是否连接
     */
    public boolean isConnect() {
        return webSocket != null && isConnect;
    }

    /**
     * 关闭
     */
    public void onClose() {
        isConnect = false;
        webSocket = null;

    }


    /**
     * 订阅
     */
    public void onSubscribe() {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("op", "subscribe");

        JSONArray jsonArray = new JSONArray();

        fetchManager.robotConfigList.forEach(item -> {
            String symbol = item.getSymbolName().toUpperCase();
            symbol = symbol.replace("USDT", "");


            JSONObject argobject = new JSONObject();
            argobject.put("channel", "mark-price");
            argobject.put("instType", "SWAP");
            argobject.put("instId", symbol + "-USDT-SWAP");


            jsonArray.add(argobject);

            JSONObject argobjectindex = new JSONObject();
            argobjectindex.put("channel", "index-tickers");
            argobjectindex.put("instType", "SWAP");
            argobjectindex.put("instId", symbol + "-USDT");

            jsonArray.add(argobjectindex);

            JSONObject argobjecttickers = new JSONObject();
            argobjecttickers.put("channel", "tickers");
            argobjecttickers.put("instType", "SWAP");
            argobjecttickers.put("instId", symbol + "-USDT-SWAP");


            jsonArray.add(argobjecttickers);
        });


        jsonObject.put("args", jsonArray);

        sendMessage(jsonObject.toJSONString());


    }

    /**
     * 发送消息
     *
     * @param str
     * @return
     */
    public boolean sendMessage(String str) {
        if (!isConnect()) return false;
        return webSocket.send(str);
    }


}
